﻿
namespace n_LCC
{
using System;
using System.Globalization;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using n_ImagePanel;
using System.Drawing;
using System.Drawing.Drawing2D;
using c_FormMover;

//编译器
public static class LCC
{
	//编译器信息
	public static string CompMes;
	public static string WordResult;
	public static string ParseResult;
	public static string ASMResult;
	public static string HexResult;
	
	static int hexnumer;
	
	static LabelNode[] LabelList;
	static int LabLength;
	
	static MacroNode[] MacrolList;
	static int MacroLength;
	
	static string[][] Parser;
	static int PLength;
	
	static int LabelIndex;
	
	//==================================================
	
	//编译器初始化
	public static void Init()
	{
		LabelList = new LabelNode[256];
		MacrolList = new MacroNode[256];
	}
	
	//编译器复位
	public static void Reset()
	{
		WordResult = "";
		ParseResult = "";
		ASMResult = "";
		HexResult = "";
		CompMes = "";
		
		hexnumer = 0;
		
		LabLength = 0;
		MacroLength = 0;
		LabelIndex = 0;
	}
	
	//设置语法树
	public static string SetParser( string ps )
	{
		Parser = new string[20][];
		PLength = -1;
		
		string[] cut = ps.Split( '\n' );
		
		int j = 0;
		for( int i = 0; i < cut.Length; ++i ) {
			string ss = cut[i].Replace( '\t', ' ' );
			ss = ss.Trim( ' ' );
			if( ss == "" ) {
				continue;
			}
			if( ss.StartsWith( "#定义 " ) ) {
				PLength++;
				Parser[PLength] = new string[30];
				Parser[PLength][0] = ss;
				j = 1;
				continue;
			}
			Parser[PLength][j] = ss;
			j++;
		}
		PLength++;
		
		string rr = "";
		for( int i = 0; i < PLength; ++i ) {
			rr += i + ": ";
			for( j = 0; j < Parser[i].Length; ++j ) {
				if( Parser[i][j] == null ) {
					break;
				}
				rr += Parser[i][j] + "--";
			}
			rr += "\n";
		}
		return rr;
	}
	
	//==================================================
	//编译器部分
	
	//语法分析
	public static string M_Parse( string line )
	{
		int notei = line.IndexOf( "//" );
		if( notei != -1 ) {
			line = line.Remove( notei );
		}
		line = line.Replace( '\t', ' ' );
		line = line.Trim( ' ' );
		if( line == "" ) {
			return null;
		}
		string[] cut = Accid( line );
		bool isOK = false;
		int selectIndex = 0;
		string A1 = null; string A2 = null; string A3 = null; string A4 = null;
		for( selectIndex = 0; selectIndex < Parser.Length; ++selectIndex ) {
			if( Parser[selectIndex] == null ) {
				break;
			}
			string[] pas = Parser[selectIndex][0].Split( ' ' );
			bool ok = true;
			for( int i = 0; i < cut.Length; ++i ) {
				
				if( i + 1 >= pas.Length ) {
					if( cut[i] != null ) {
						ok = false;
					}
					break;
				}
				if( pas[i+1] == "@1" ) {
					A1 = cut[i];
					continue;
				}
				if( pas[i+1] == "@2" ) {
					A2 = cut[i];
					continue;
				}
				if( pas[i+1] == "@3" ) {
					A3 = cut[i];
					continue;
				}
				if( pas[i+1] == "@4" ) {
					A4 = cut[i];
					continue;
				}
				if( pas[i+1] != cut[i] ) {
					ok = false;
					break;
				}
				if( pas[i+1] == null && cut[i] == null ) {
					break;
				}
			}
			if( ok ) {
				isOK = true;
				break;
			}
		}
		//设置词法分析结果
		string tr = "";
		for( int i = 0; i < cut.Length; ++i ) {
			if( cut[i] == null ) {
				break;
			}
			tr += cut[i] + " ";
		}
		WordResult += tr + "\n";
		
		//判断是否有匹配的语法树
		if( !isOK ) {
			ParseResult += "未匹配: " + tr + "\n";
			ASMResult += tr + "\n";
		}
		else {
			ParseResult += "源: " + line + "\n\t模板: " + Parser[selectIndex][0] + "\n";
			for( int i = 1; i < Parser[selectIndex].Length; ++i ) {
				if( Parser[selectIndex][i] == null ) {
					break;
				}
				ParseResult += "\t输出: " + Parser[selectIndex][i] + "\n";
				string asm = Parser[selectIndex][i].Replace( "@1", A1 ).Replace( "@2", A2 ).Replace( "@3", A3 ).Replace( "@4", A4 );
				if( asm.IndexOf( "&" ) != -1 ) {
					asm = asm.Replace( "&", "sys_label" + LabelIndex + "_" );
				}
				ASMResult += asm + "\n";
			}
			LabelIndex++;
		}
		return null;
	}
	
	//标签提取
	public static string M_GetLabel( string source, ref string code )
	{
		CompMes += "标签与宏定义列表:\n";
		
		string[] s = source.Split( '\n' );
		
		string err = null;
		int LabelAddr = 0;
		for( int i = 0; i < s.Length; ++i ) {
			string line = s[i];
			line = line.Trim( ' ' );
			
			//判断是否为标号
			if( line.EndsWith( ":" ) ) {
				string lab = line.Remove( line.Length - 1 ).Trim( ' ' );
				AddLabel( lab, LabelAddr );
				CompMes += "标签名称:" + lab + "  地址:" + LabelAddr + "\n";
				continue;
			}
			//判断是否为宏定义
			else if( line.StartsWith( "# define " ) ) {
				line = line.Remove( 0, 9 );
				string[] mc = line.Split( ' ' );
				if( mc.Length < 3 ) {
					err = "宏定义格式不正确, 需要为 #define name value  (" + line + ")";
					continue;
				}
				string uname = mc[0].Trim( ' ' );
				mc[0] = "";
				string tname = String.Join( " ", mc ).Trim( ' ' );
				AddMacro( uname, tname );
				CompMes += "宏名称:" + uname + "  值:" + tname + "\n";
				continue;
			}
			else {
				code += line + "\n";
			}
			LabelAddr++;
		}
		return err;
	}
	
	//地址标签替换
	public static string M_RepLabel( ref string line )
	{
		string[] cut = Accid( line );
		for( int n = 0; n < cut.Length; ++n ) {
			if( cut[n] == null ) {
				break;
			}
			for( int i = 0; i < LabLength; ++i ) {
				if( cut[n] == LabelList[i].Name ) {
					cut[n] = LabelList[i].Addr.ToString();
				}
			}
			for( int i = 0; i < MacroLength; ++i ) {
				if( cut[n] == MacrolList[i].SName ) {
					cut[n] = MacrolList[i].TName;
				}
			}
		}
		//设置词法分析结果
		line = "";
		for( int i = 0; i < cut.Length; ++i ) {
			if( cut[i] == null ) {
				break;
			}
			line += cut[i] + " ";
		}
		return null;
	}
	
	//输出到机器码文件流 (任意进制数字统一转成十六进制并加上 "0x" 前缀
	public static string M_ToHexFile( string line )
	{
		string err = null;
		
		try {
		//两种方法都可以
		//using System.Data;
		//int n = (int)new DataTable().Compute(line, null);
		
		int n = Calculate( line.ToLower(), ref err );
		line = n.ToString( "X" ).PadLeft( 2, '0' );
		
		HexResult += line + " ";
		hexnumer++;
		if( hexnumer % 10 == 0 ) {
			HexResult += "\n";
		}
		
		}
		catch {
			err = "计算出错: " + line;
		}
		
		return err;
	}
	
	//-----------------------------------
	//分析词法
	static string[] Accid( string Source )
	{
		int Line = 0;
		string[] List = new string[50];
		int lidx = 0;
		
		int i = 0;
		while( i < Source.Length ) {
			
			//读取字符常量
			char c = Source[ i ];
			
			//判断是否分界符
			if( c == '{' || c == '}' || c == ';' || c == ',' || c == ':' || c == '(' || c == ')' ||
			    c == '.' || c == '?' ) {
				List[lidx] = c.ToString(); ++lidx;
				++i;
				continue;
			}
			//判断是否空白符
			if( c == '\n' ) {
				++Line;
				++i;
				continue;
			}
			//判断是否空白符
			if( c == ' ' || c == '\t' || c == (char)13 ) {
				++i;
				continue;
			}
			//判断是否注释
			if( c == '/' && i + 1 < Source.Length && Source[ i + 1 ] == '/' ) {
				while( i < Source.Length && Source[ i ] != '\n' ) {
					++i;
				}
				continue;
			}
			//判断是否标识符
			if( isLetter( c ) ) {
				string Result = "";
				do {
					Result += Source[ i ].ToString();
					++i;
				}
				while( i < Source.Length && isLetter( Source[ i ] ) );
				List[lidx] = Result; ++lidx;
				continue;
			}
			//判断是否运算符
			if( isOper( c ) ) {
				string Result = "";
				do {
					Result += Source[ i ].ToString();
					++i;
				}
				while( i < Source.Length && isOper( Source[ i ] ) );
				List[lidx] = Result; ++lidx;
				continue;
			}
			//防护
			List[lidx] = c.ToString(); ++lidx;
			++i;
		}
		return List;
	}
	
	static bool isLetter( char c )
	{
		return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_';
	}
	
	static bool isOper( char c )
	{
		return c == '+' || c == '-' || c == '*' || c == '/' || c == '%' || c == '=' || c == '>' || c == '<' ||
			   c == '^' || c == '&' || c == '|';
	}
	
	//-----------------------------------
	//内部功能
	
	//添加label
	static void AddLabel( string name, int addr )
	{
		LabelList[LabLength] = new LabelNode( name, addr );
		LabLength++;
	}
	
	//添加宏定义
	static void AddMacro( string SName, string TName )
	{
		MacrolList[MacroLength] = new MacroNode( SName, TName );
		MacroLength++;
	}
	
	//计算数值
	static int GetValue( string line, ref string err )
	{
		int Number = 0;
		
		try {
		if( line.StartsWith( "0x" ) ) {
			line = line.Remove( 0, 2 );
			Number = int.Parse( line, NumberStyles.HexNumber );
		}
		else if( line.StartsWith( "0b" ) ) {
			line = line.Remove( 0, 2 );
			int Base = 1;
			for( int j = line.Length - 1; j >= 0; --j ) {
				int bit = (int)line[ j ] - 0x30;
				if( bit > 1 ) {
					err = "非法的二进制数据格式: " + line;
				}
				Number += bit * Base;
				Base *= 2;
			}
		}
		else {
			Number = int.Parse( line );
		}
		} catch {
			err = "数字解析出错";
		}
		return Number;
	}
	
	//-----------------------------------
	//表达式计算器, 目前暂不支持单目运算
	
	static int Calculate(string _exp, ref string err )
	{
		Stack operandStack = new Stack();//操作数
		Stack operatorStack = new Stack();//运算符
		operatorStack.Push('#');
		char[] exp = (_exp + "#").ToCharArray();
		StringBuilder sb = new StringBuilder();
		
		for (int i = 0; i < exp.Length; i++) {
			if( exp[i] == ' ' ) {
				continue;
			}
			if (IsPerand(exp[i])) {
				sb.Append(exp[i]);
			}
			else {
				string sbstr = sb.ToString();
				if (sbstr!="") {
					operandStack.Push(sb);
				}
				sb = new StringBuilder();
				//优先级大于当前栈顶运算符的优先级
				if (PriorityBeforeIn(exp[i]) > priorityAferIn((char)operatorStack.Peek())) {
					operatorStack.Push(exp[i]);//#*
				}
				else if (PriorityBeforeIn(exp[i]) < priorityAferIn((char)operatorStack.Peek()))
				{
					object sbd =operandStack.Pop();
					string str = sbd.ToString();
					object sbd1 =operandStack.Pop();
					string str1 = sbd1.ToString();
					int dou= GetValue(str, ref err );
					int dou1= GetValue(str1, ref err );
					operandStack.Push(Count((char)operatorStack.Pop(),dou,dou1));
					i--;
				}
				else if (PriorityBeforeIn(exp[i]) == priorityAferIn((char)operatorStack.Peek()))
				{
					if (exp[i] == ')')
					{
						while (true)
						{
							char c = (char)operatorStack.Peek();
							if (c == '(')
							{
								operatorStack.Pop();
								break;
							}
							object sbd = operandStack.Pop();
							string str = sbd.ToString();
							object sbd1 = operandStack.Pop();
							string str1 = sbd1.ToString();
							int dou= GetValue(str, ref err );
							int dou1= GetValue(str1, ref err );
							operandStack.Push(Count((char)operatorStack.Pop(), dou, dou1));
						}
					}
					else if (exp[i] == '#')
					{
						while (true)
						{
							char c = (char)operatorStack.Peek();
							if (c == '#')
							{
								operatorStack.Pop();
								break;
							}
							object sbd = operandStack.Pop();
							string str = sbd.ToString();
							object sbd1 = operandStack.Pop();
							string str1 = sbd1.ToString();
							int dou= GetValue(str, ref err );
							int dou1= GetValue(str1, ref err );
							operandStack.Push(Count((char)operatorStack.Pop(), dou, dou1));
						}
					}
				}
			}
		}
		object o = operandStack.Pop();
		if( o is int ) {
			return (int)o;
		}
		else {
			return GetValue( ((StringBuilder)o).ToString(), ref err );
		}
	}
	
	//判断字符是否为操作数
	static bool IsPerand(char c)
	{
		bool flag = c >= '0' && c <= '9' || c >= 'a' && c <= 'z';
		return flag;
	}
	
	//获取操作符入栈前的优先级
	static int PriorityBeforeIn(char _opertor)
	{
		int priority = -1;
		switch (_opertor)
		{
			case '#':
				priority = 0;
				break;
			case '(':
				priority = 8;
				break;
			case '^':
				priority = 6;
				break;
			case '*':
			case '/':
			case '%':
				priority = 4;
				break;
			case '+':
			case '-':
				priority = 2;
				break;
			case ')':
				priority = 1;
				break;
			default:
				break;
		}
		return priority;
	}
	
	//获取操作符入站后的优先级
	static int priorityAferIn(char _operator)
	{
		int priority = -1;
		switch (_operator)
		{
			case '#':
				priority = 0;
				break;
			case '(':
				priority = 1;
				break;
			case '^':
				priority = 7;
				break;
			case '*':
			case '/':
			case '%':
				priority = 5;
				break;
			case '+':
			case '-':
				priority = 3;
				break;
			case ')':
				priority = 8;
				break;
			default:
				break;
		}
		return priority;

	}
	
	//按照指定操作对两个数字进行相应的计算
	static int Count(char _operator, int a, int b)
	{
		int result = 0;
		switch (_operator)
		{
			case '*':
				result = b * a;
				break;
			case '/':
				result = b / a;
				break;
			case '%':
				result = b % a;
				break;
			case '+':
				result = b + a;
				break;
			case '-':
				result = b - a;
				break;
			default:
				break;
		}
		return result;
	}
	
	//=======================================
	
	class MacroNode
	{
		public string SName;
		public string TName;
		
		//构造函数
		public MacroNode( string n, string a )
		{
			SName = n;
			TName = a;
		}
	}
	
	class LabelNode
	{
		public string Name;
		public int Addr;
		
		//构造函数
		public LabelNode( string n, int a )
		{
			Name = n;
			Addr = a;
		}
	}
}
}


